1   /*
2    * Copyright (C) 2008 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import static com.google.common.truth.Truth.assertThat;
20  import static java.util.Arrays.asList;
21  
22  import com.google.common.annotations.GwtCompatible;
23  import com.google.common.annotations.GwtIncompatible;
24  import com.google.common.collect.testing.ListTestSuiteBuilder;
25  import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
26  import com.google.common.collect.testing.features.CollectionFeature;
27  import com.google.common.collect.testing.features.CollectionSize;
28  import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetAsListGenerator;
29  import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetCopyOfGenerator;
30  import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetDescendingAsListGenerator;
31  import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetDescendingGenerator;
32  import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitComparator;
33  import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitSuperclassComparatorGenerator;
34  import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetReversedOrderGenerator;
35  import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetAsListGenerator;
36  import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetUnhashableGenerator;
37  import com.google.common.collect.testing.testers.SetHashCodeTester;
38  import com.google.common.testing.NullPointerTester;
39  import com.google.common.testing.SerializableTester;
40  
41  import junit.framework.Test;
42  import junit.framework.TestSuite;
43  
44  import java.util.Arrays;
45  import java.util.Collection;
46  import java.util.Collections;
47  import java.util.Comparator;
48  import java.util.Iterator;
49  import java.util.NoSuchElementException;
50  import java.util.Set;
51  import java.util.SortedSet;
52  import java.util.TreeSet;
53  
54  /**
55   * Unit tests for {@link ImmutableSortedSet}.
56   *
57   * @author Jared Levy
58   */
59  @GwtCompatible(emulated = true)
60  public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
61  
62    @GwtIncompatible("suite")
63    public static Test suite() {
64      TestSuite suite = new TestSuite();
65  
66      suite.addTest(NavigableSetTestSuiteBuilder.using(
67          new ImmutableSortedSetCopyOfGenerator())
68          .named(ImmutableSortedSetTest.class.getName())
69          .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
70              CollectionFeature.SERIALIZABLE,
71              CollectionFeature.ALLOWS_NULL_QUERIES)
72              .createTestSuite());
73  
74      suite.addTest(NavigableSetTestSuiteBuilder.using(
75          new ImmutableSortedSetExplicitComparator())
76          .named(ImmutableSortedSetTest.class.getName()
77              + ", explicit comparator, vararg")
78              .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
79                  CollectionFeature.SERIALIZABLE,
80                  CollectionFeature.ALLOWS_NULL_QUERIES)
81                  .createTestSuite());
82  
83      suite.addTest(NavigableSetTestSuiteBuilder.using(
84          new ImmutableSortedSetExplicitSuperclassComparatorGenerator())
85          .named(ImmutableSortedSetTest.class.getName()
86              + ", explicit superclass comparator, iterable")
87              .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
88                  CollectionFeature.SERIALIZABLE,
89                  CollectionFeature.ALLOWS_NULL_QUERIES)
90                  .createTestSuite());
91  
92      suite.addTest(NavigableSetTestSuiteBuilder.using(
93          new ImmutableSortedSetReversedOrderGenerator())
94          .named(ImmutableSortedSetTest.class.getName()
95              + ", reverseOrder, iterator")
96              .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
97                  CollectionFeature.SERIALIZABLE,
98                  CollectionFeature.ALLOWS_NULL_QUERIES)
99                  .createTestSuite());
100 
101     suite.addTest(NavigableSetTestSuiteBuilder.using(
102         new ImmutableSortedSetUnhashableGenerator())
103         .suppressing(SetHashCodeTester.getHashCodeMethods())
104         .named(ImmutableSortedSetTest.class.getName() + ", unhashable")
105         .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
106             CollectionFeature.ALLOWS_NULL_QUERIES)
107             .createTestSuite());
108 
109     suite.addTest(NavigableSetTestSuiteBuilder.using(
110         new ImmutableSortedSetDescendingGenerator())
111         .named(ImmutableSortedSetTest.class.getName() + ", descending")
112         .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
113             CollectionFeature.SERIALIZABLE,
114             CollectionFeature.ALLOWS_NULL_QUERIES)
115             .createTestSuite());
116 
117     suite.addTest(ListTestSuiteBuilder.using(
118         new ImmutableSortedSetAsListGenerator())
119         .named("ImmutableSortedSet.asList")
120         .withFeatures(CollectionSize.ANY,
121             CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
122             CollectionFeature.SERIALIZABLE,
123             CollectionFeature.ALLOWS_NULL_QUERIES)
124             .createTestSuite());
125 
126     suite.addTest(ListTestSuiteBuilder.using(
127         new ImmutableSortedSetSubsetAsListGenerator())
128         .named("ImmutableSortedSet.subSet.asList")
129         .withFeatures(CollectionSize.ANY,
130             CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
131             CollectionFeature.SERIALIZABLE,
132             CollectionFeature.ALLOWS_NULL_QUERIES)
133             .createTestSuite());
134 
135     suite.addTest(ListTestSuiteBuilder.using(
136         new ImmutableSortedSetDescendingAsListGenerator())
137         .named("ImmutableSortedSet.descendingSet.asList")
138         .withFeatures(CollectionSize.ANY,
139             CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
140             CollectionFeature.SERIALIZABLE,
141             CollectionFeature.ALLOWS_NULL_QUERIES)
142             .createTestSuite());
143 
144     suite.addTestSuite(ImmutableSortedSetTest.class);
145 
146     return suite;
147   }
148 
149   // enum singleton pattern
150   private enum StringLengthComparator implements Comparator<String> {
151     INSTANCE;
152 
153     @Override
154     public int compare(String a, String b) {
155       return a.length() - b.length();
156     }
157   }
158 
159   private static final Comparator<String> STRING_LENGTH
160       = StringLengthComparator.INSTANCE;
161 
162   @Override protected SortedSet<String> of() {
163     return ImmutableSortedSet.of();
164   }
165 
166   @Override protected SortedSet<String> of(String e) {
167     return ImmutableSortedSet.of(e);
168   }
169 
170   @Override protected SortedSet<String> of(String e1, String e2) {
171     return ImmutableSortedSet.of(e1, e2);
172   }
173 
174   @Override protected SortedSet<String> of(String e1, String e2, String e3) {
175     return ImmutableSortedSet.of(e1, e2, e3);
176   }
177 
178   @Override protected SortedSet<String> of(
179       String e1, String e2, String e3, String e4) {
180     return ImmutableSortedSet.of(e1, e2, e3, e4);
181   }
182 
183   @Override protected SortedSet<String> of(
184       String e1, String e2, String e3, String e4, String e5) {
185     return ImmutableSortedSet.of(e1, e2, e3, e4, e5);
186   }
187 
188   @Override protected SortedSet<String> of(String e1, String e2, String e3,
189       String e4, String e5, String e6, String... rest) {
190     return ImmutableSortedSet.of(e1, e2, e3, e4, e5, e6, rest);
191   }
192 
193   @Override protected SortedSet<String> copyOf(String[] elements) {
194     return ImmutableSortedSet.copyOf(elements);
195   }
196 
197   @Override protected SortedSet<String> copyOf(Collection<String> elements) {
198     return ImmutableSortedSet.copyOf(elements);
199   }
200 
201   @Override protected SortedSet<String> copyOf(Iterable<String> elements) {
202     return ImmutableSortedSet.copyOf(elements);
203   }
204 
205   @Override protected SortedSet<String> copyOf(Iterator<String> elements) {
206     return ImmutableSortedSet.copyOf(elements);
207   }
208 
209   @GwtIncompatible("NullPointerTester")
210   public void testNullPointers() {
211     new NullPointerTester().testAllPublicStaticMethods(ImmutableSortedSet.class);
212   }
213 
214   public void testEmpty_comparator() {
215     SortedSet<String> set = of();
216     assertSame(Ordering.natural(), set.comparator());
217   }
218 
219   public void testEmpty_headSet() {
220     SortedSet<String> set = of();
221     assertSame(set, set.headSet("c"));
222   }
223 
224   public void testEmpty_tailSet() {
225     SortedSet<String> set = of();
226     assertSame(set, set.tailSet("f"));
227   }
228 
229   public void testEmpty_subSet() {
230     SortedSet<String> set = of();
231     assertSame(set, set.subSet("c", "f"));
232   }
233 
234   public void testEmpty_first() {
235     SortedSet<String> set = of();
236     try {
237       set.first();
238       fail();
239     } catch (NoSuchElementException expected) {
240     }
241   }
242 
243   public void testEmpty_last() {
244     SortedSet<String> set = of();
245     try {
246       set.last();
247       fail();
248     } catch (NoSuchElementException expected) {
249     }
250   }
251 
252   @GwtIncompatible("SerializableTester")
253   public void testEmpty_serialization() {
254     SortedSet<String> set = of();
255     SortedSet<String> copy = SerializableTester.reserialize(set);
256     assertSame(set, copy);
257   }
258 
259   public void testSingle_comparator() {
260     SortedSet<String> set = of("e");
261     assertSame(Ordering.natural(), set.comparator());
262   }
263 
264   public void testSingle_headSet() {
265     SortedSet<String> set = of("e");
266     assertTrue(set.headSet("g") instanceof ImmutableSortedSet);
267     assertThat(set.headSet("g")).has().item("e");
268     assertSame(of(), set.headSet("c"));
269     assertSame(of(), set.headSet("e"));
270   }
271 
272   public void testSingle_tailSet() {
273     SortedSet<String> set = of("e");
274     assertTrue(set.tailSet("c") instanceof ImmutableSortedSet);
275     assertThat(set.tailSet("c")).has().item("e");
276     assertThat(set.tailSet("e")).has().item("e");
277     assertSame(of(), set.tailSet("g"));
278   }
279 
280   public void testSingle_subSet() {
281     SortedSet<String> set = of("e");
282     assertTrue(set.subSet("c", "g") instanceof ImmutableSortedSet);
283     assertThat(set.subSet("c", "g")).has().item("e");
284     assertThat(set.subSet("e", "g")).has().item("e");
285     assertSame(of(), set.subSet("f", "g"));
286     assertSame(of(), set.subSet("c", "e"));
287     assertSame(of(), set.subSet("c", "d"));
288   }
289 
290   public void testSingle_first() {
291     SortedSet<String> set = of("e");
292     assertEquals("e", set.first());
293   }
294 
295   public void testSingle_last() {
296     SortedSet<String> set = of("e");
297     assertEquals("e", set.last());
298   }
299 
300   @GwtIncompatible("SerializableTester")
301   public void testSingle_serialization() {
302     SortedSet<String> set = of("e");
303     SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
304     assertEquals(set.comparator(), copy.comparator());
305   }
306 
307   public void testOf_ordering() {
308     SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
309     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
310   }
311 
312   /*
313    * Tests that we workaround GWT bug #3621 (or that it is already fixed).
314    *
315    * A call to of() with a parameter that is not a plain Object[] (here,
316    * Interface[]) creates a RegularImmutableSortedSet backed by an array of that
317    * type. Later, RegularImmutableSortedSet.toArray() calls System.arraycopy()
318    * to copy from that array to the destination array. This would be fine, but
319    * GWT has a bug: It refuses to copy from an E[] to an Object[] when E is an
320    * interface type.
321    */
322   // TODO: test other collections for this problem
323   public void testOf_gwtArraycopyBug() {
324     /*
325      * The test requires:
326      *
327      * 1) An interface I extending Comparable<I> so that the created array is of
328      * an interface type. 2) An instance of a class implementing that interface
329      * so that we can pass non-null instances of the interface.
330      *
331      * (Currently it's safe to pass instances for which compareTo() always
332      * returns 0, but if we had a SingletonImmutableSortedSet, this might no
333      * longer be the case.)
334      *
335      * javax.naming.Name and java.util.concurrent.Delayed might work, but
336      * they're fairly obscure, we've invented our own interface and class.
337      */
338     Interface a = new Impl();
339     Interface b = new Impl();
340     ImmutableSortedSet<Interface> set = ImmutableSortedSet.of(a, b);
341     set.toArray();
342     set.toArray(new Object[2]);
343   }
344 
345   interface Interface extends Comparable<Interface> {
346   }
347   static class Impl implements Interface {
348     static int nextId;
349     Integer id = nextId++;
350 
351     @Override public int compareTo(Interface other) {
352       return id.compareTo(((Impl) other).id);
353     }
354   }
355 
356   public void testOf_ordering_dupes() {
357     SortedSet<String> set = of("e", "a", "e", "f", "b", "b", "d", "a", "c");
358     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
359   }
360 
361   public void testOf_comparator() {
362     SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
363     assertSame(Ordering.natural(), set.comparator());
364   }
365 
366   public void testOf_headSet() {
367     SortedSet<String> set = of("e", "f", "b", "d", "c");
368     assertTrue(set.headSet("e") instanceof ImmutableSortedSet);
369     assertThat(set.headSet("e")).has().exactly("b", "c", "d").inOrder();
370     assertThat(set.headSet("g")).has().exactly("b", "c", "d", "e", "f").inOrder();
371     assertSame(of(), set.headSet("a"));
372     assertSame(of(), set.headSet("b"));
373   }
374 
375   public void testOf_tailSet() {
376     SortedSet<String> set = of("e", "f", "b", "d", "c");
377     assertTrue(set.tailSet("e") instanceof ImmutableSortedSet);
378     assertThat(set.tailSet("e")).has().exactly("e", "f").inOrder();
379     assertThat(set.tailSet("a")).has().exactly("b", "c", "d", "e", "f").inOrder();
380     assertSame(of(), set.tailSet("g"));
381   }
382 
383   public void testOf_subSet() {
384     SortedSet<String> set = of("e", "f", "b", "d", "c");
385     assertTrue(set.subSet("c", "e") instanceof ImmutableSortedSet);
386     assertThat(set.subSet("c", "e")).has().exactly("c", "d").inOrder();
387     assertThat(set.subSet("a", "g")).has().exactly("b", "c", "d", "e", "f").inOrder();
388     assertSame(of(), set.subSet("a", "b"));
389     assertSame(of(), set.subSet("g", "h"));
390     assertSame(of(), set.subSet("c", "c"));
391     try {
392       set.subSet("e", "c");
393       fail();
394     } catch (IllegalArgumentException expected) {
395     }
396   }
397 
398   @GwtIncompatible("SerializableTester")
399   public void testOf_subSetSerialization() {
400     SortedSet<String> set = of("e", "f", "b", "d", "c");
401     SerializableTester.reserializeAndAssert(set.subSet("c", "e"));
402   }
403 
404   public void testOf_first() {
405     SortedSet<String> set = of("e", "f", "b", "d", "c");
406     assertEquals("b", set.first());
407   }
408 
409   public void testOf_last() {
410     SortedSet<String> set = of("e", "f", "b", "d", "c");
411     assertEquals("f", set.last());
412   }
413 
414   @GwtIncompatible("SerializableTester")
415   public void testOf_serialization() {
416     SortedSet<String> set = of("e", "f", "b", "d", "c");
417     SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
418     assertTrue(Iterables.elementsEqual(set, copy));
419     assertEquals(set.comparator(), copy.comparator());
420   }
421 
422   /* "Explicit" indicates an explicit comparator. */
423 
424   public void testExplicit_ordering() {
425     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
426         "in", "the", "quick", "jumped", "over", "a").build();
427     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
428   }
429 
430   public void testExplicit_ordering_dupes() {
431     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
432         "in", "the", "quick", "brown", "fox", "jumped",
433         "over", "a", "lazy", "dog").build();
434     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
435   }
436 
437   public void testExplicit_contains() {
438     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
439         "in", "the", "quick", "jumped", "over", "a").build();
440     assertTrue(set.contains("quick"));
441     assertTrue(set.contains("google"));
442     assertFalse(set.contains(""));
443     assertFalse(set.contains("california"));
444     assertFalse(set.contains(null));
445   }
446 
447   public void testExplicit_containsMismatchedTypes() {
448     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
449         "in", "the", "quick", "jumped", "over", "a").build();
450     assertFalse(set.contains(3.7));
451   }
452 
453   public void testExplicit_comparator() {
454     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
455         "in", "the", "quick", "jumped", "over", "a").build();
456     assertSame(STRING_LENGTH, set.comparator());
457   }
458 
459   public void testExplicit_headSet() {
460     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
461         "in", "the", "quick", "jumped", "over", "a").build();
462     assertTrue(set.headSet("a") instanceof ImmutableSortedSet);
463     assertTrue(set.headSet("fish") instanceof ImmutableSortedSet);
464     assertThat(set.headSet("fish")).has().exactly("a", "in", "the").inOrder();
465     assertThat(set.headSet("california")).has()
466         .exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
467     assertTrue(set.headSet("a").isEmpty());
468     assertTrue(set.headSet("").isEmpty());
469   }
470 
471   public void testExplicit_tailSet() {
472     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
473         "in", "the", "quick", "jumped", "over", "a").build();
474     assertTrue(set.tailSet("california") instanceof ImmutableSortedSet);
475     assertTrue(set.tailSet("fish") instanceof ImmutableSortedSet);
476     assertThat(set.tailSet("fish")).has().exactly("over", "quick", "jumped").inOrder();
477     assertThat(
478         set.tailSet("a")).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
479     assertTrue(set.tailSet("california").isEmpty());
480   }
481 
482   public void testExplicit_subSet() {
483     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
484         "in", "the", "quick", "jumped", "over", "a").build();
485     assertTrue(set.subSet("the", "quick") instanceof ImmutableSortedSet);
486     assertTrue(set.subSet("", "b") instanceof ImmutableSortedSet);
487     assertThat(set.subSet("the", "quick")).has().exactly("the", "over").inOrder();
488     assertThat(set.subSet("a", "california"))
489         .has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
490     assertTrue(set.subSet("", "b").isEmpty());
491     assertTrue(set.subSet("vermont", "california").isEmpty());
492     assertTrue(set.subSet("aaa", "zzz").isEmpty());
493     try {
494       set.subSet("quick", "the");
495       fail();
496     } catch (IllegalArgumentException expected) {
497     }
498   }
499 
500   public void testExplicit_first() {
501     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
502         "in", "the", "quick", "jumped", "over", "a").build();
503     assertEquals("a", set.first());
504   }
505 
506   public void testExplicit_last() {
507     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
508         "in", "the", "quick", "jumped", "over", "a").build();
509     assertEquals("jumped", set.last());
510   }
511 
512   @GwtIncompatible("SerializableTester")
513   public void testExplicitEmpty_serialization() {
514     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).build();
515     SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
516     assertTrue(set.isEmpty());
517     assertTrue(copy.isEmpty());
518     assertSame(set.comparator(), copy.comparator());
519   }
520 
521   @GwtIncompatible("SerializableTester")
522   public void testExplicit_serialization() {
523     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
524         "in", "the", "quick", "jumped", "over", "a").build();
525     SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
526     assertTrue(Iterables.elementsEqual(set, copy));
527     assertSame(set.comparator(), copy.comparator());
528   }
529 
530   public void testCopyOf_ordering() {
531     SortedSet<String> set =
532         copyOf(asList("e", "a", "f", "b", "d", "c"));
533     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
534   }
535 
536   public void testCopyOf_ordering_dupes() {
537     SortedSet<String> set =
538         copyOf(asList("e", "a", "e", "f", "b", "b", "d", "a", "c"));
539     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
540   }
541 
542   public void testCopyOf_subSet() {
543     SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
544     SortedSet<String> subset = set.subSet("c", "e");
545     SortedSet<String> copy = copyOf(subset);
546     assertEquals(subset, copy);
547   }
548 
549   public void testCopyOf_headSet() {
550     SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
551     SortedSet<String> headset = set.headSet("d");
552     SortedSet<String> copy = copyOf(headset);
553     assertEquals(headset, copy);
554   }
555 
556   public void testCopyOf_tailSet() {
557     SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
558     SortedSet<String> tailset = set.tailSet("d");
559     SortedSet<String> copy = copyOf(tailset);
560     assertEquals(tailset, copy);
561   }
562 
563   public void testCopyOf_comparator() {
564     SortedSet<String> set = copyOf(asList("e", "a", "f", "b", "d", "c"));
565     assertSame(Ordering.natural(), set.comparator());
566   }
567 
568   public void testCopyOf_iterator_ordering() {
569     SortedSet<String> set = copyOf(asIterator("e", "a", "f", "b", "d", "c"));
570     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
571   }
572 
573   public void testCopyOf_iterator_ordering_dupes() {
574     SortedSet<String> set =
575         copyOf(asIterator("e", "a", "e", "f", "b", "b", "d", "a", "c"));
576     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
577   }
578 
579   public void testCopyOf_iterator_comparator() {
580     SortedSet<String> set = copyOf(asIterator("e", "a", "f", "b", "d", "c"));
581     assertSame(Ordering.natural(), set.comparator());
582   }
583 
584   public void testCopyOf_sortedSet_ordering() {
585     SortedSet<String> set =
586         copyOf(Sets.newTreeSet(asList("e", "a", "f", "b", "d", "c")));
587     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
588   }
589 
590   public void testCopyOf_sortedSet_comparator() {
591     SortedSet<String> set = copyOf(Sets.<String>newTreeSet());
592     assertSame(Ordering.natural(), set.comparator());
593   }
594 
595   public void testCopyOfExplicit_ordering() {
596     SortedSet<String> set =
597         ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
598             "in", "the", "quick", "jumped", "over", "a"));
599     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
600   }
601 
602   public void testCopyOfExplicit_ordering_dupes() {
603     SortedSet<String> set =
604         ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
605             "in", "the", "quick", "brown", "fox", "jumped", "over", "a",
606             "lazy", "dog"));
607     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
608   }
609 
610   public void testCopyOfExplicit_comparator() {
611     SortedSet<String> set =
612         ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
613             "in", "the", "quick", "jumped", "over", "a"));
614     assertSame(STRING_LENGTH, set.comparator());
615   }
616 
617   public void testCopyOfExplicit_iterator_ordering() {
618     SortedSet<String> set =
619         ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
620             "in", "the", "quick", "jumped", "over", "a"));
621     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
622   }
623 
624   public void testCopyOfExplicit_iterator_ordering_dupes() {
625     SortedSet<String> set =
626         ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
627             "in", "the", "quick", "brown", "fox", "jumped", "over", "a",
628             "lazy", "dog"));
629     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
630   }
631 
632   public void testCopyOfExplicit_iterator_comparator() {
633     SortedSet<String> set =
634         ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
635             "in", "the", "quick", "jumped", "over", "a"));
636     assertSame(STRING_LENGTH, set.comparator());
637   }
638 
639   public void testCopyOf_sortedSetIterable() {
640     SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH);
641     Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a");
642     SortedSet<String> set = copyOf(input);
643     assertThat(set).has().exactly("a", "in", "jumped", "over", "quick", "the").inOrder();
644   }
645 
646   public void testCopyOfSorted_natural_ordering() {
647     SortedSet<String> input = Sets.newTreeSet(
648         asList("in", "the", "quick", "jumped", "over", "a"));
649     SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
650     assertThat(set).has().exactly("a", "in", "jumped", "over", "quick", "the").inOrder();
651   }
652 
653   public void testCopyOfSorted_natural_comparator() {
654     SortedSet<String> input =
655         Sets.newTreeSet(asList("in", "the", "quick", "jumped", "over", "a"));
656     SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
657     assertSame(Ordering.natural(), set.comparator());
658   }
659 
660   public void testCopyOfSorted_explicit_ordering() {
661     SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH);
662     Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a");
663     SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
664     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
665     assertSame(STRING_LENGTH, set.comparator());
666   }
667 
668   public void testEquals_bothDefaultOrdering() {
669     SortedSet<String> set = of("a", "b", "c");
670     assertEquals(set, Sets.newTreeSet(asList("a", "b", "c")));
671     assertEquals(Sets.newTreeSet(asList("a", "b", "c")), set);
672     assertFalse(set.equals(Sets.newTreeSet(asList("a", "b", "d"))));
673     assertFalse(Sets.newTreeSet(asList("a", "b", "d")).equals(set));
674     assertFalse(set.equals(Sets.newHashSet(4, 5, 6)));
675     assertFalse(Sets.newHashSet(4, 5, 6).equals(set));
676   }
677 
678   public void testEquals_bothExplicitOrdering() {
679     SortedSet<String> set = of("in", "the", "a");
680     assertEquals(Sets.newTreeSet(asList("in", "the", "a")), set);
681     assertFalse(set.equals(Sets.newTreeSet(asList("in", "the", "house"))));
682     assertFalse(Sets.newTreeSet(asList("in", "the", "house")).equals(set));
683     assertFalse(set.equals(Sets.newHashSet(4, 5, 6)));
684     assertFalse(Sets.newHashSet(4, 5, 6).equals(set));
685 
686     Set<String> complex = Sets.newTreeSet(STRING_LENGTH);
687     Collections.addAll(complex, "in", "the", "a");
688     assertEquals(set, complex);
689   }
690 
691   public void testEquals_bothDefaultOrdering_StringVsInt() {
692     SortedSet<String> set = of("a", "b", "c");
693     assertFalse(set.equals(Sets.newTreeSet(asList(4, 5, 6))));
694     assertNotEqualLenient(Sets.newTreeSet(asList(4, 5, 6)), set);
695   }
696 
697   public void testEquals_bothExplicitOrdering_StringVsInt() {
698     SortedSet<String> set = of("in", "the", "a");
699     assertFalse(set.equals(Sets.newTreeSet(asList(4, 5, 6))));
700     assertNotEqualLenient(Sets.newTreeSet(asList(4, 5, 6)), set);
701   }
702 
703   public void testContainsAll_notSortedSet() {
704     SortedSet<String> set = of("a", "b", "f");
705     assertTrue(set.containsAll(Collections.emptyList()));
706     assertTrue(set.containsAll(asList("b")));
707     assertTrue(set.containsAll(asList("b", "b")));
708     assertTrue(set.containsAll(asList("b", "f")));
709     assertTrue(set.containsAll(asList("b", "f", "a")));
710     assertFalse(set.containsAll(asList("d")));
711     assertFalse(set.containsAll(asList("z")));
712     assertFalse(set.containsAll(asList("b", "d")));
713     assertFalse(set.containsAll(asList("f", "d", "a")));
714   }
715 
716   public void testContainsAll_sameComparator() {
717     SortedSet<String> set = of("a", "b", "f");
718     assertTrue(set.containsAll(Sets.newTreeSet()));
719     assertTrue(set.containsAll(Sets.newTreeSet(asList("b"))));
720     assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "f"))));
721     assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "b", "f"))));
722     assertFalse(set.containsAll(Sets.newTreeSet(asList("d"))));
723     assertFalse(set.containsAll(Sets.newTreeSet(asList("z"))));
724     assertFalse(set.containsAll(Sets.newTreeSet(asList("b", "d"))));
725     assertFalse(set.containsAll(Sets.newTreeSet(asList("f", "d", "a"))));
726   }
727 
728   public void testContainsAll_sameComparator_StringVsInt() {
729     SortedSet<String> set = of("a", "b", "f");
730     SortedSet<Integer> unexpected = Sets.newTreeSet(Ordering.natural());
731     unexpected.addAll(asList(1, 2, 3));
732     assertFalse(set.containsAll(unexpected));
733   }
734 
735   public void testContainsAll_differentComparator() {
736     Comparator<Comparable<?>> comparator = Collections.reverseOrder();
737     SortedSet<String> set = new ImmutableSortedSet.Builder<String>(comparator)
738         .add("a", "b", "f").build();
739     assertTrue(set.containsAll(Sets.newTreeSet()));
740     assertTrue(set.containsAll(Sets.newTreeSet(asList("b"))));
741     assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "f"))));
742     assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "b", "f"))));
743     assertFalse(set.containsAll(Sets.newTreeSet(asList("d"))));
744     assertFalse(set.containsAll(Sets.newTreeSet(asList("z"))));
745     assertFalse(set.containsAll(Sets.newTreeSet(asList("b", "d"))));
746     assertFalse(set.containsAll(Sets.newTreeSet(asList("f", "d", "a"))));
747   }
748 
749   @GwtIncompatible("SerializableTester")
750   public void testDifferentComparator_serialization() {
751     // don't use Collections.reverseOrder(); it didn't reserialize to the same instance in JDK5
752     Comparator<Comparable<?>> comparator = Ordering.natural().reverse();
753     SortedSet<String> set = new ImmutableSortedSet.Builder<String>(comparator)
754         .add("a", "b", "c").build();
755     SortedSet<String> copy = SerializableTester.reserializeAndAssert(set);
756     assertTrue(Iterables.elementsEqual(set, copy));
757     assertEquals(set.comparator(), copy.comparator());
758   }
759 
760   public void testReverseOrder() {
761     SortedSet<String> set = ImmutableSortedSet.<String>reverseOrder()
762         .add("a", "b", "c").build();
763     assertThat(set).has().exactly("c", "b", "a").inOrder();
764     assertEquals(Ordering.natural().reverse(), set.comparator());
765   }
766 
767   private static final Comparator<Object> TO_STRING
768       = new Comparator<Object>() {
769           @Override
770           public int compare(Object o1, Object o2) {
771             return o1.toString().compareTo(o2.toString());
772           }
773         };
774 
775   public void testSupertypeComparator() {
776     SortedSet<Integer> set = new ImmutableSortedSet.Builder<Integer>(TO_STRING)
777         .add(3, 12, 101, 44).build();
778     assertThat(set).has().exactly(101, 12, 3, 44).inOrder();
779   }
780 
781   public void testSupertypeComparatorSubtypeElements() {
782     SortedSet<Number> set = new ImmutableSortedSet.Builder<Number>(TO_STRING)
783         .add(3, 12, 101, 44).build();
784     assertThat(set).has().exactly(101, 12, 3, 44).inOrder();
785   }
786 
787   @Override <E extends Comparable<E>> ImmutableSortedSet.Builder<E> builder() {
788     return ImmutableSortedSet.naturalOrder();
789   }
790 
791   @Override int getComplexBuilderSetLastElement() {
792     return 0x00FFFFFF;
793   }
794 
795   public void testLegacyComparable_of() {
796     ImmutableSortedSet<LegacyComparable> set0 = ImmutableSortedSet.of();
797 
798     @SuppressWarnings("unchecked") // using a legacy comparable
799     ImmutableSortedSet<LegacyComparable> set1 = ImmutableSortedSet.of(
800         LegacyComparable.Z);
801 
802     @SuppressWarnings("unchecked") // using a legacy comparable
803     ImmutableSortedSet<LegacyComparable> set2 = ImmutableSortedSet.of(
804         LegacyComparable.Z, LegacyComparable.Y);
805   }
806 
807   public void testLegacyComparable_copyOf_collection() {
808     ImmutableSortedSet<LegacyComparable> set
809         = ImmutableSortedSet.copyOf(LegacyComparable.VALUES_BACKWARD);
810     assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_FORWARD, set));
811   }
812 
813   public void testLegacyComparable_copyOf_iterator() {
814     ImmutableSortedSet<LegacyComparable> set = ImmutableSortedSet.copyOf(
815         LegacyComparable.VALUES_BACKWARD.iterator());
816     assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_FORWARD, set));
817   }
818 
819   public void testLegacyComparable_builder_natural() {
820     @SuppressWarnings("unchecked")
821     // Note: IntelliJ wrongly reports an error for this statement
822     ImmutableSortedSet.Builder<LegacyComparable> builder
823         = ImmutableSortedSet.<LegacyComparable>naturalOrder();
824 
825     builder.addAll(LegacyComparable.VALUES_BACKWARD);
826     builder.add(LegacyComparable.X);
827     builder.add(LegacyComparable.Y, LegacyComparable.Z);
828 
829     ImmutableSortedSet<LegacyComparable> set = builder.build();
830     assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_FORWARD, set));
831   }
832 
833   public void testLegacyComparable_builder_reverse() {
834     @SuppressWarnings("unchecked")
835     // Note: IntelliJ wrongly reports an error for this statement
836     ImmutableSortedSet.Builder<LegacyComparable> builder
837         = ImmutableSortedSet.<LegacyComparable>reverseOrder();
838 
839     builder.addAll(LegacyComparable.VALUES_FORWARD);
840     builder.add(LegacyComparable.X);
841     builder.add(LegacyComparable.Y, LegacyComparable.Z);
842 
843     ImmutableSortedSet<LegacyComparable> set = builder.build();
844     assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_BACKWARD, set));
845   }
846 
847   @SuppressWarnings({"deprecation", "static-access"})
848   public void testBuilderMethod() {
849     try {
850       ImmutableSortedSet.builder();
851       fail();
852     } catch (UnsupportedOperationException expected) {
853     }
854   }
855 
856   public void testAsList() {
857     ImmutableSet<String> set = ImmutableSortedSet.of("a", "e", "i", "o", "u");
858     ImmutableList<String> list = set.asList();
859     assertEquals(ImmutableList.of("a", "e", "i", "o", "u"), list);
860     assertSame(list, ImmutableList.copyOf(set));
861   }
862 
863   @GwtIncompatible("SerializableTester, ImmutableSortedAsList")
864   public void testAsListReturnTypeAndSerialization() {
865     ImmutableSet<String> set = ImmutableSortedSet.of("a", "e", "i", "o", "u");
866     ImmutableList<String> list = set.asList();
867     assertTrue(list instanceof ImmutableSortedAsList);
868     ImmutableList<String> copy = SerializableTester.reserializeAndAssert(list);
869     assertTrue(copy instanceof ImmutableSortedAsList);
870   }
871 
872   public void testSubsetAsList() {
873     ImmutableSet<String> set
874         = ImmutableSortedSet.of("a", "e", "i", "o", "u").subSet("c", "r");
875     ImmutableList<String> list = set.asList();
876     assertEquals(ImmutableList.of("e", "i", "o"), list);
877     assertEquals(list, ImmutableList.copyOf(set));
878   }
879 
880   @GwtIncompatible("SerializableTester, ImmutableSortedAsList")
881   public void testSubsetAsListReturnTypeAndSerialization() {
882     ImmutableSet<String> set
883         = ImmutableSortedSet.of("a", "e", "i", "o", "u").subSet("c", "r");
884     ImmutableList<String> list = set.asList();
885     assertTrue(list instanceof ImmutableSortedAsList);
886     ImmutableList<String> copy = SerializableTester.reserializeAndAssert(list);
887     assertTrue(copy instanceof ImmutableSortedAsList);
888   }
889 
890   public void testAsListInconsistentComprator() {
891     ImmutableSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
892         "in", "the", "quick", "jumped", "over", "a").build();
893     ImmutableList<String> list = set.asList();
894     assertTrue(list.contains("the"));
895     assertEquals(2, list.indexOf("the"));
896     assertEquals(2, list.lastIndexOf("the"));
897     assertFalse(list.contains("dog"));
898     assertEquals(-1, list.indexOf("dog"));
899     assertEquals(-1, list.lastIndexOf("dog"));
900     assertFalse(list.contains("chicken"));
901     assertEquals(-1, list.indexOf("chicken"));
902     assertEquals(-1, list.lastIndexOf("chicken"));
903   }
904 
905   private static <E> Iterator<E> asIterator(E... elements) {
906     return asList(elements).iterator();
907   }
908 
909   // In GWT, java.util.TreeSet throws ClassCastException when the comparator
910   // throws it, unlike JDK6.  Therefore, we accept ClassCastException as a
911   // valid result thrown by java.util.TreeSet#equals.
912   private static void assertNotEqualLenient(
913       TreeSet<?> unexpected, SortedSet<?> actual) {
914     try {
915       assertThat(actual).isNotEqualTo(unexpected);
916     } catch (ClassCastException accepted) {
917     }
918   }
919 
920   public void testHeadSetInclusive() {
921     String[] strings = NUMBER_NAMES.toArray(new String[0]);
922     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
923     Arrays.sort(strings);
924     for (int i = 0; i < strings.length; i++) {
925       assertThat(set.headSet(strings[i], true))
926           .has().exactlyAs(sortedNumberNames(0, i + 1)).inOrder();
927     }
928   }
929 
930   public void testHeadSetExclusive() {
931     String[] strings = NUMBER_NAMES.toArray(new String[0]);
932     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
933     Arrays.sort(strings);
934     for (int i = 0; i < strings.length; i++) {
935       assertThat(set.headSet(strings[i], false)).has().exactlyAs(
936           sortedNumberNames(0, i)).inOrder();
937     }
938   }
939 
940   public void testTailSetInclusive() {
941     String[] strings = NUMBER_NAMES.toArray(new String[0]);
942     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
943     Arrays.sort(strings);
944     for (int i = 0; i < strings.length; i++) {
945       assertThat(set.tailSet(strings[i], true)).has().exactlyAs(
946           sortedNumberNames(i, strings.length)).inOrder();
947     }
948   }
949 
950   public void testTailSetExclusive() {
951     String[] strings = NUMBER_NAMES.toArray(new String[0]);
952     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
953     Arrays.sort(strings);
954     for (int i = 0; i < strings.length; i++) {
955       assertThat(set.tailSet(strings[i], false)).has().exactlyAs(
956           sortedNumberNames(i + 1, strings.length)).inOrder();
957     }
958   }
959 
960   public void testSubSetExclusiveExclusive() {
961     String[] strings = NUMBER_NAMES.toArray(new String[0]);
962     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
963     Arrays.sort(strings);
964     for (int i = 0; i < strings.length; i++) {
965       for (int j = i; j < strings.length; j++) {
966         assertThat(set.subSet(strings[i], false, strings[j], false))
967             .has().exactlyAs(sortedNumberNames(Math.min(i + 1, j), j)).inOrder();
968       }
969     }
970   }
971 
972   public void testSubSetInclusiveExclusive() {
973     String[] strings = NUMBER_NAMES.toArray(new String[0]);
974     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
975     Arrays.sort(strings);
976     for (int i = 0; i < strings.length; i++) {
977       for (int j = i; j < strings.length; j++) {
978         assertThat(set.subSet(strings[i], true, strings[j], false))
979             .has().exactlyAs(sortedNumberNames(i, j)).inOrder();
980       }
981     }
982   }
983 
984   public void testSubSetExclusiveInclusive() {
985     String[] strings = NUMBER_NAMES.toArray(new String[0]);
986     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
987     Arrays.sort(strings);
988     for (int i = 0; i < strings.length; i++) {
989       for (int j = i; j < strings.length; j++) {
990         assertThat(set.subSet(strings[i], false, strings[j], true))
991             .has().exactlyAs(sortedNumberNames(i + 1, j + 1)).inOrder();
992       }
993     }
994   }
995 
996   public void testSubSetInclusiveInclusive() {
997     String[] strings = NUMBER_NAMES.toArray(new String[0]);
998     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
999     Arrays.sort(strings);
1000     for (int i = 0; i < strings.length; i++) {
1001       for (int j = i; j < strings.length; j++) {
1002         assertThat(set.subSet(strings[i], true, strings[j], true))
1003             .has().exactlyAs(sortedNumberNames(i, j + 1)).inOrder();
1004       }
1005     }
1006   }
1007 
1008   private static ImmutableList<String> sortedNumberNames(int i, int j) {
1009     return ImmutableList.copyOf(SORTED_NUMBER_NAMES.subList(i, j));
1010   }
1011 
1012   private static final ImmutableList<String> NUMBER_NAMES =
1013       ImmutableList.of("one", "two", "three", "four", "five", "six", "seven");
1014 
1015   private static final ImmutableList<String> SORTED_NUMBER_NAMES =
1016       Ordering.natural().immutableSortedCopy(NUMBER_NAMES);
1017 
1018   private static class SelfComparableExample implements Comparable<SelfComparableExample> {
1019     @Override
1020     public int compareTo(SelfComparableExample o) {
1021       return 0;
1022     }
1023   }
1024 
1025   public void testBuilderGenerics_SelfComparable() {
1026     ImmutableSortedSet.Builder<SelfComparableExample> natural = ImmutableSortedSet.naturalOrder();
1027     ImmutableSortedSet.Builder<SelfComparableExample> reverse = ImmutableSortedSet.reverseOrder();
1028   }
1029 
1030   private static class SuperComparableExample extends SelfComparableExample {}
1031 
1032   public void testBuilderGenerics_SuperComparable() {
1033     ImmutableSortedSet.Builder<SuperComparableExample> natural = ImmutableSortedSet.naturalOrder();
1034     ImmutableSortedSet.Builder<SuperComparableExample> reverse = ImmutableSortedSet.reverseOrder();
1035   }
1036 }